package interface_class;

import polymorphic.D;

/**
 * @author : niu niu
 * @version : 1.0.0
 * @date : 2022/9/22 20:46
 * 接口
 *      更加"纯粹"的抽象类 ，表示一种规范，一种能力
 *      定义：
 *          1.使用interface关键字定义接口，接口中只有全局常量和抽象方法（JDK8之前，也是当前使用设计使用的接口）
 *              子类使用implements表示实现一个父接口，必须覆写接口中的所有抽象方法
 *          2. 正因为接口中普遍只存在全局变量和抽象方法，因此，接口中public、abstract、static、final统统可以省略不写！
 *              阿里编码规约中要求，接口中这些关键字都不出现
 *              只有接口可以省略（public），抽象类中不写就是 default包 权限
 *          3. 接口也无法直接实例化对象，只能子类向上转型为其实例化
 *
 *          4. 一个子类可以同时使用implements 关键字实现多个父接口（开发中的接口优先原则）
 *                  接口的多实现
 *          5.接口和类之间的关系：子类同时继承父类和实现接口的顺序 ：先extends，再implements
 *              若有子类同时需要继承一个抽象类，实现父接口，
 *                  先使用extends继承父类，然后使用implements实现接口
 *
 *          6.从JDK8开始，接口中也允许存在普通方法，接口中的普通方法使用default关键字定义
 *              有方法体，子类实现接口后可以直接使用接口中的普通方法
 *
 *
 *          命名规范： 除了一些特殊的接口（现实存在的特殊接口），接口一般采用大写的 I 开头，子类使用impl结尾表示是一个接口的实现子类
 */
public class Demo_Interface {
    public static void main(String[] args) {
        //多态，向上转型的经典实现
        //千万不要呗前面的类和接口所迷惑，就看new在哪
        USB usb = new Mouse();
        usb.plugIn();
        usb.work();
        //java: 无法为最终变量MSG分配值
//        usb.MSG="aa";
        System.out.println(USB.MSG);

        Cat cat =new Cat();
        Dog dog = new Dog();
        Duck duck = new Duck();
        duck.normalFly();//接口中使用default实现的普通方法：可以直接调用
        runTest(cat);
        runTest(dog);
        runTest(duck);
        swimTest(dog);
        swimTest(duck);
        flyTest(duck);

    }

    //定义这个方法时，采用的接口参数，接受所有该接口的子类
    //都属于向上转型（多态）
    //用父接口作为 参数，实现参数统一化
    public static void runTest(IRun iRun){
        iRun.run();
    }
    public static void flyTest(IFly iFly){
        iFly.fly();
    }
    public static void swimTest(ISwim iSwim){
        iSwim.swim();
    }
}
